Skip to content

chore(ci): unblock the App Store release job and refresh the pinned toolchain - #2670

Merged
ethicnology merged 4 commits into
developfrom
chore/flutter-3.44.9
Aug 12, 2026
Merged

chore(ci): unblock the App Store release job and refresh the pinned toolchain#2670
ethicnology merged 4 commits into
developfrom
chore/flutter-3.44.9

Conversation

@ethicnology

Copy link
Copy Markdown
Member

The first App Store Connect release run (#31634557049) failed at Install locked CocoaPods dependencies. The macos-15 image now ships CocoaPods 1.17.0, whose podspec checksums differ from the 1.16.2 that generated ios/Podfile.lock, so pod install --deployment refused to run — correctly, that is what deployment mode is for. All six signing secrets validated, so the failure is toolchain drift, not configuration.

While fixing that, the pinned Flutter and FVM versions were also stale.

What this changes

Three independent commits, readable in order:

  1. chore: bump flutter to 3.44.9.fvmrc, the three pubspec.yaml flutter pins, pubspec.lock, and the Containerfile.tools dev-container default. Picks up the 3.44.6 → 3.44.9 hotfixes (iOS hang when a debugged app crashes, lipo verification failure under the Xcode 27 toolchain, external-texture resource leak on some GPUs, two Android/Linux build crashes). Dart stays on 3.12.2, so no sdk: constraint moves anywhere.
  2. chore(ci): bump fvm to 4.1.2 — the App Store workflow, the flutter-setup composite action, and the tools image. Both pinned release checksums were recomputed and verified (0b2a1469… macos-arm64, 12b06566… linux-x64); as a control, recomputing the 4.1.1 linux-x64 checksum reproduced the value already pinned in the tree. The iOS workflow URL also moves from conceptadev/fvm to leoafarias/fvm — the former only resolved through a GitHub rename redirect, and both URLs were confirmed to serve byte-identical archives.
  3. ci(ios): pin cocoapods to the version Podfile.lock was built with — reads COCOAPODS: back from the lockfile and installs exactly that version through a RubyGems version selector (pod _1.16.2_ install), leaving the image's own CocoaPods in place. The lockfile becomes the single source of truth in both directions: it survives the next image rotation, and it follows automatically when a developer regenerates the pods on a newer CocoaPods.

What this does not change

  • No application code, no dependency versions, no generated sources — make build-runner produces an empty diff on 3.44.9.
  • The Flutter 3.47 line, released 2026-08-11, is deliberately left for a separate PR: it moves Dart and carries real breaking changes, unlike this patch-level bump.
  • The Podfile.lock itself is regenerated on macOS in a follow-up, since pod install needs the Apple toolchain. Commit 3 is what makes the job green either way.

Picks up the 3.44.6 through 3.44.9 hotfixes: an iOS hang when a debugged
app crashes, a lipo verification failure under the Xcode 27 toolchain, an
external-texture resource leak on some GPUs, and two Android/Linux build
crashes. Dart stays on 3.12.2, so no SDK constraint moves.
Refreshes both pinned release checksums (macos-arm64 for the App Store
workflow, linux-x64 for the tools image) and switches the iOS workflow to
the leoafarias/fvm URL, which the conceptadev one only reached through a
GitHub rename redirect. Both assets verified to be byte-identical.
The macos-15 image moved to CocoaPods 1.17, whose podspec checksums differ
from the 1.16.2 that generated Podfile.lock, so pod install --deployment
aborted the release job. Read the version back from the lockfile instead of
hardcoding one, so the lockfile stays authoritative when either side moves.
@claude

claude Bot commented Aug 12, 2026

Copy link
Copy Markdown

Claude finished @ethicnology's task in 4m 19s —— View job


Review: correctness, security, regressions

  • Gather context: diff vs origin/develop, read changed files
  • Verify version consistency across .fvmrc / pubspec files / Containerfile / workflows
  • Verify FVM release checksums and URL move (attempted — network egress blocked in this environment, see finding 2)
  • Review the CocoaPods lockfile-pinning shell logic in the workflow
  • Post review summary

Note: I can't create formal inline review comments from this integration, so findings are listed here with file/line references.


🔴 1. Commit fba70b006 hand-edits the Podfile.lock footer and defeats the fix (blocker)

The branch now contains a 4th commit (chore: cocoa pods 1.17.0) that isn't in the PR description. It changes exactly one line — ios/Podfile.lock:53 from COCOAPODS: 1.16.2 to COCOAPODS: 1.17.0 — while the SPEC CHECKSUMS block (lines 42–49) is still the one CocoaPods 1.16.2 computed. This is a hand edit of generated provenance metadata, not a regenerated lockfile.

Consequences:

  • The pin step this PR adds (.github/workflows/upload-app-store-connect.yml:189-195) reads the footer, gets 1.17.0, finds it equal to the image's CocoaPods, skips the gem install, and runs pod _1.17.0_ install --deployment — which is byte-for-byte the configuration that failed in run #31634557049. By this PR's own root cause (1.17.0 computes different podspec checksums than the ones recorded in the lockfile), --deployment will reject again. Commit 3's fix is nullified.
  • It breaks the invariant the PR establishes: "the lockfile is the single source of truth" only holds if the footer records the version that actually wrote the file. It now claims 1.17.0 generated a file 1.17.0 never touched.
  • The PR description now contradicts the branch ("Total commits: 3"; "The Podfile.lock itself is regenerated on macOS in a follow-up").

Fix: either revert fba70b006 (commit 3 alone makes the job green on 1.16.2 — that was its whole point), or replace it with a lockfile fully regenerated by running pod install under CocoaPods 1.17.0 on macOS, per the PR's own follow-up plan. Fix this →

🟡 2. FVM checksums are unverified by this review

The two new pinned hashes (0b2a1469… macos-arm64 at upload-app-store-connect.yml:131, 12b06566… linux-x64 at Containerfile.tools:194) gate which binary runs on the runner that later holds signing keys, and the URL move conceptadevleoafarias changes which account is trusted. The PR body describes a sound verification (including the 4.1.1 control recomputation), but network egress is blocked in this review environment, so I could not reproduce the hashes. Given what these pins protect, a second maintainer should independently run shasum -a 256 on both release assets before merge.

🔵 3. Minor notes on the CocoaPods pin step (non-blocking)

  • sudo gem install cocoapods -v "$locked_version" --no-document pins the top-level gem only; its transitive gem dependencies resolve fresh from RubyGems at run time on the signing runner. Same trust class as the image's own CocoaPods, so acceptable — just be aware the "single source of truth" covers the cocoapods version, not its dependency closure.
  • If a future image ships pod via Homebrew instead of a RubyGems binstub, the _${version}_ selector won't dispatch — but the test "$(pod "_${locked_version}_" --version)" guard at line 194 makes that fail loudly rather than silently using the wrong version. Good defensive design.
  • .github/actions/flutter-setup/action.yml:54 still pipes https://fvm.app/install.sh | bash while the release workflow and Containerfile.tools moved to pinned, checksummed tarballs. Pre-existing pattern and those jobs hold no signing secrets, but the posture now diverges; worth unifying eventually.

✅ What checks out

  • Flutter 3.44.9 is consistent across .fvmrc, pubspec.yaml, both package pubspecs, pubspec.lock, and Containerfile.tools; Dart stays 3.12.2 everywhere, no stale 3.44.2/4.1.1 references remain (the pubspec.lock:279 "4.1.1" is an unrelated Dart package).
  • FVM 4.1.2 is consistent across the workflow, the composite action, and the tools image; the leoafarias URL matches what Containerfile.tools already used.
  • The awk '/^COCOAPODS:/ …' parsing is guarded (test -n, exact-version assertion before use) and the CocoaPods cache key already derives from hashFiles('ios/Podfile.lock'), so it self-invalidates.
  • The "build-runner produces an empty diff" claim is enforced mechanically by the workflow's own porcelain check (upload-app-store-connect.yml:176-180); the Analyze and Test run was still in progress at review time (run).

Summary: the workflow pin logic (commit 3) and the toolchain bumps (commits 1–2) look correct and well-guarded. The late hand-edit of Podfile.lock (finding 1) undoes the fix and should be reverted or replaced with a properly regenerated lockfile before merge; the FVM hashes deserve one independent verification (finding 2).

@ethicnology
ethicnology merged commit 48cbcd8 into develop Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants